import time from '../timeTools'
const version = '1.0.0' // 版本号
const _callbacks = {} // 回调映射，将回调函数用id唯一标识，客户端通过id执行回调
let _startCallbacks = [] // 注入有延时，注入之前的调用全部缓存到这个变量，注入成功之后依次执行
let _callApp // 原生

function _isAndroid () {
  return /android/i.test(navigator.userAgent)
}

function _isIOS () {
  return /iphone|ipad|ios/i.test(navigator.userAgent)
}

/**
 * JSBridge的CallApp的方法，用于提供统一的调用APP的方法
 *
 * @actionName 需要调用native方法的actionName
 * @params     需要携带的数据
 * @callBack   返回结果回调 function(error, data)  (可选)
 */
function callApp (actionName, params, callback) {
  console.log("callApp")

  const data = {}
  data.action = actionName
  if (callback) {
    const callbackId = 'func' + time.getTodayTimeStamp()
    _callbacks[callbackId] = callback
    data.jsCallBackId = callbackId
  }
  if (params) {
    data.params = params
  }
  // 注入了callFlutter
  if (window.callFlutter) {
    console.log("window.callFlutter")
    // eslint-disable-next-line
    callFlutter.postMessage(JSON.stringify(data))
    return
  }
  // 注入还未成功时，添加到缓存队列中（注入成功后，自动调用队列中的方法）
  if (!_callApp) {
    _startCallbacks.push(data)
    return
  }
  // 注入成功时，直接调用
  _callApp(data)
}

/**
 * 用于提供统一的APP使用的调用方法
 *
 * @params.jsCallBackId 用于执行的JS回调的方法名(可选)
 * @params.data         用于执行的JS回调的数据(可选)
 * @error.message       错误信息
 * @error.code          错误代码
 */
function appCallBack (params, error) {
  if (typeof params === 'string') {
    params = JSON.parse(params)
  }
  const { jsCallBackId, data } = params
  if (jsCallBackId) {
    /* 从字典中取出回调函数,并传递数据执行 */
    const callback = _callbacks[jsCallBackId]
    if (callback) {
      callback(data, error)
    }
  }
}

// 检测js是否注入成功
// eslint-disable-next-line
let check_times = 30

function check () {
  // eslint-disable-next-line
  check_times--
  // eslint-disable-next-line
  if (check_times <= 0) {
    console.log('YMDDJSAPI check timeout', true)
    return
  }
  //调用ios
  if (_isIOS()) {
    if (window.ISIOSNative) {
      _callApp = bridgeInfo =>
        window.ISIOSNative.callApp(
          JSON.stringify({
            message: bridgeInfo
          })
        )
    } else if (
      window.webkit &&
      window.webkit.messageHandlers &&
      window.webkit.messageHandlers.ISIOSNative
    ) {
      _callApp = bridgeInfo =>
        // eslint-disable-next-line
        window.webkit.messageHandlers.ISIOSNative.postMessage({
          message: bridgeInfo
        })
    } else {
      setTimeout(check, 100)
      return
    }
  } else if (_isAndroid()) { // 调用android
    if (window.ISANDNative && window.ISANDNative.CallApp) {
      _callApp = bridgeInfo =>
        window.ISANDNative.CallApp(JSON.stringify(bridgeInfo))
    } else {
      setTimeout(check, 100)
      return
    }
  }

  for (let i = 0, { length } = _startCallbacks; i < length; i++) {
    _callApp(_startCallbacks[i])
  }
  _startCallbacks = []
}

check()

const ISJSBridge = {
  version,
  callApp,
  AppCallBack: appCallBack,
  checkSuccess: false
}

window.ISJSBridge = ISJSBridge

export default ISJSBridge
